package com.sds.sweng.swat.miplatform.service.figures.components;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Element;
import org.dom4j.Node;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Cursors;
import org.eclipse.draw2d.FreeformLayeredPane;
import org.eclipse.draw2d.FreeformLayout;
import org.eclipse.draw2d.GridData;
import org.eclipse.draw2d.GridLayout;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.draw2d.geometry.Rectangle;

import com.sds.sweng.swat.miplatform.service.graphics.ComponentDrawer;
import com.sds.sweng.swat.miplatform.service.graphics.ComponentUtils;

public class TabComponent extends FreeformLayeredPane implements MiplatformComponent {

	protected Node component;
	protected Node parent;
	protected ComponentDrawer drawer;

	protected int headerHeight;

	protected List<Node> tabPages;
	protected List<ComponentDrawer> tabPageDrawers;
	protected List<Label> tabHeaders;

	protected GridLayout headerLayout;

	protected FreeformLayeredPane headerPane;
	protected List<FreeformLayeredPane> bodyPanes;

	public TabComponent(Node component, Node parent, ComponentDrawer drawer) {
		this.component = component;
		this.parent = parent;
		this.drawer = drawer;

		setBounds(ComponentUtils.getComponentBound(component, parent));
		setSize(getBounds().width, getBounds().height);
		setLayoutManager(new FreeformLayout());

		initComponent();
	}

	protected void initComponent() {
		String tabPageTop = component.selectSingleNode("Contents/TabPage").valueOf("@Top");

		if (!StringUtils.isEmpty(tabPageTop)) {
			headerHeight = Integer.parseInt(tabPageTop);
		}

		tabPages = component.selectNodes("Contents/TabPage");

		drawTabHeaders();
		drawTabBodies();

		int tabIndex = 0;

		if (!StringUtils.isEmpty(component.valueOf("@TabIndex"))) {
			tabIndex = Integer.parseInt(component.valueOf("@TabIndex"));
		}

		selectTabPage(tabIndex);
	}

	protected void drawTabHeaders() {
		tabHeaders = new ArrayList<Label>();
		headerPane = new FreeformLayeredPane();
		headerPane.setBounds(new Rectangle(bounds.x, bounds.y, bounds.width, headerHeight));

		getLayoutManager().setConstraint(headerPane, headerPane.getBounds());
		add(headerPane);

		headerLayout = new GridLayout(tabPages.size(), false);
		headerLayout.marginWidth = 0;
		headerLayout.marginHeight = 0;
		headerLayout.horizontalSpacing = 0;
		headerLayout.verticalSpacing = 0;

		headerPane.setLayoutManager(headerLayout);

		for (int i=0;i<tabPages.size();i++) {
			String tabText = tabPages.get(i).valueOf("@Text");
			Label tabHeader = new Label(tabText);
			tabHeader.setBorder(new LineBorder(ColorConstants.black));
			tabHeader.setOpaque(true);

			final int tabIndex = i;

			tabHeader.addMouseListener(new MouseListener() {

				public void mouseReleased(MouseEvent me) {
					selectTabPage(tabIndex);
				}

				public void mousePressed(MouseEvent me) {
					// Ignore
				}

				public void mouseDoubleClicked(MouseEvent me) {
					// Ignore
				}
			});

			tabHeader.addMouseMotionListener(new MouseMotionListener() {

				public void mouseMoved(MouseEvent me) {
					// Ignore
				}

				public void mouseHover(MouseEvent me) {
					// Ignore
				}

				public void mouseExited(MouseEvent me) {
					setCursor(Cursors.ARROW);
				}

				public void mouseEntered(MouseEvent me) {
					setCursor(Cursors.HAND);
				}

				public void mouseDragged(MouseEvent me) {
					// Ignore
				}
			});

			tabHeaders.add(tabHeader);

			GridData gridData = new GridData();
			gridData.heightHint = headerHeight;

			headerLayout.setConstraint(tabHeader, gridData);
			headerPane.add(tabHeader);
		}
	}

	protected void drawTabBodies() {
		bodyPanes = new ArrayList<FreeformLayeredPane>();
		tabPageDrawers = new ArrayList<ComponentDrawer>();

		for (int i=0;i<tabPages.size();i++) {
			FreeformLayeredPane bodyPane = new FreeformLayeredPane();
			bodyPane.setLayoutManager(new FreeformLayout());
			bodyPane.setBounds(new Rectangle(bounds.x, bounds.y+headerHeight, bounds.width, bounds.y-headerHeight));
			bodyPane.setBorder(new LineBorder(ColorConstants.black));
			bodyPane.setOpaque(true);

			bodyPanes.add(bodyPane);

			ComponentDrawer tabPageDrawer = new ComponentDrawer(bodyPane, drawer.designArea);
			tabPageDrawer.drawAllComponents(tabPages.get(i));

			tabPageDrawers.add(tabPageDrawer);
		}
	}

	protected void selectTabPage(int tabIndex) {
		switchHeader(tabIndex);
		switchBody(tabIndex);
	}

	protected void switchHeader(int tabIndex) {
		for (Label tabHeader : tabHeaders) {
			tabHeader.setBackgroundColor(ColorConstants.white);
		}

		tabHeaders.get(tabIndex).setBackgroundColor(ColorConstants.orange);
	}


	protected void switchBody(int tabIndex) {
		try {
			remove(bodyPanes.get(tabIndex));
		} catch (Exception e) {
			// Ignore
		}

		getLayoutManager().setConstraint(bodyPanes.get(tabIndex), bodyPanes.get(tabIndex).getBounds());
		add(bodyPanes.get(tabIndex));
	}


	public void setDrawer(ComponentDrawer drawer) {
		this.drawer = drawer;
	}

	public Node getNode() {
		return component;
	}

	public String getId() {
		Element parent = component.getParent();
		String id = component.valueOf("@Id");

		while (!"Form".equals(parent.getName())) {
			String parentId = parent.valueOf("@Id");

			if (!StringUtils.isEmpty(parentId)) {
				id = parentId + "." + id;
			}

			parent = parent.getParent();
		}

		return id;
	}

}
